package com.fotoloka.services.impl;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.imageio.ImageIO;
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintException;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.OrientationRequested;

import br.com.fotoxbh.geracao.Gerador4Fotos;
import br.com.fotoxbh.geracao.Gerador4FotosPadrao;
import br.com.fotoxbh.geracao.old.GerarVeroka;

import com.fotoloka.dto.Chave;
import com.fotoloka.services.FotoService;
import com.fotoloka.services.SerializadorService;
import com.fotoloka.util.ParamUtil;
import com.fotoloka.view.Janela;

public class FotoServiceImpl implements FotoService {

	private static FotoServiceImpl instance;

	private static final int fotoPorSecao = Janela.FOTOS_POR_VEZ;

	private SerializadorService serializador;

	private Chave chaves;

	private FotoServiceImpl() {
		serializador = new SerializadorServiceImpl();
		iniciar();
	}

	public static FotoServiceImpl getInstance() {
		if (instance == null) {
			instance = new FotoServiceImpl();
		}
		return instance;
	}

	public FotoServiceImpl(SerializadorService serializadorService) {
		this.serializador = serializadorService;
	}

	private void iniciar() {
		chaves = serializador.deserializeChaves();
		if (chaves == null) {
			chaves = new Chave(1, 1);
			serializador.serializeChaves(chaves);
		} else {
			if(chaves.getNumeroFoto() != 1) {
				chaves.setNumeroSecao(chaves.getNumeroSecao() + 1);
				chaves.setNumeroFoto(1);
				serializador.serializeChaves(chaves);
			}
		}
	}

	public void incrementar() {
		chaves = serializador.deserializeChaves();
		if (chaves == null) {
			throw new RuntimeException(
					"O FotoService deve ser iniciado pelo método iniciar()");
		}
		if (chaves.getNumeroFoto() >= fotoPorSecao) {
			chaves.setNumeroSecao(chaves.getNumeroSecao() + 1);
			chaves.setNumeroFoto(1);
		} else {
			chaves.setNumeroFoto(chaves.getNumeroFoto() + 1);
		}
		serializador.serializeChaves(chaves);
	}

	@Override
	public void armazenar(BufferedImage image) throws IOException {
		String diretorio = chaves.getDiretorioSecao();
		String nomeArquivo = chaves.getNomeFoto();
		File dirSecao = new File(diretorio);
		if (!dirSecao.exists()) {
			dirSecao.mkdir();
		}
		File outputfile = new File(diretorio, nomeArquivo);
		ImageIO.write(image, "jpg", outputfile);
		incrementar();
	}

	@Override
	public BufferedImage getFoto(int secao, int numero) throws IOException {
		Chave chaveFoto = new Chave(secao, numero);
		File file = new File(chaveFoto.getDiretorioSecao(),
				chaveFoto.getNomeFoto());
		return ImageIO.read(file);
	}

	public void reset() {
		// deleteDir(new File(dirFotos));
	}

	public boolean deleteDir(File dir) {
		if (dir.isDirectory()) {
			String[] children = dir.list();
			for (int i = 0; i < children.length; i++) {
				boolean success = deleteDir(new File(dir, children[i]));
				if (!success) {
					return false;
				}
			}
		}
		// Agora o diretório está vazio, restando apenas deletá-lo.
		return dir.delete();
	}

	@Override
	public File gerarFotoImpressao() throws IOException {
		
		int secao = getUltimaSecao();
		
		Image foto1 = getFoto(secao, 1);
		Image foto2 = getFoto(secao, 2);
		Image foto3 = getFoto(secao, 3);
		Image foto4 = getFoto(secao, 4);
		
		String diretorio = chaves.getDiretorioSecaoAnterior();
		File finalImage = new File(chaves.getDiretorioImpressao(), "secao_" + secao + ".jpg");
		
		//FIXME alterar para o proximo evento
		return Gerador4Fotos.gerarFotoLeiaute(finalImage, foto1, foto2, foto3, foto4);
	}
	
	public BufferedImage gerarFotoImpressaoOld(int secao) throws IOException {
		int larguraFoto = 480 * 5; //960;
		int alturaFoto = 393 * 5; //544;
		
		int xInicial = 0;
		int yInicial = 320 * 5;
		
		int espacoX = 10 * 5;
		int espacoY = 10 * 5;

		int x1 = xInicial + espacoX;
		int y1 = yInicial + espacoY;

		int x2 = xInicial + espacoX;
		int y2 = yInicial + (espacoY*5) + alturaFoto;
		
		int x3 = xInicial + (espacoX*3) + larguraFoto;
		int y3 = yInicial + espacoY;
		
		int x4 = xInicial + (espacoX*3) + larguraFoto;
		int y4 = yInicial + (espacoY*5) + alturaFoto;
		
		BufferedImage verde = ImageIO.read(new File("verde.jpg"));
		BufferedImage vermelho = ImageIO.read(new File("vermelho.jpg"));
		
		Image foto1 = getFoto(secao, 1).getScaledInstance(larguraFoto, alturaFoto, Image.SCALE_AREA_AVERAGING);
		Image foto2 = getFoto(secao, 2).getScaledInstance(larguraFoto, alturaFoto, Image.SCALE_AREA_AVERAGING);
		Image foto3 = getFoto(secao, 3).getScaledInstance(larguraFoto, alturaFoto, Image.SCALE_AREA_AVERAGING);
		Image foto4 = getFoto(secao, 4).getScaledInstance(larguraFoto, alturaFoto, Image.SCALE_AREA_AVERAGING);
		
		BufferedImage img = ImageIO.read(new File("formato-3.jpg"));
		img.createGraphics().drawImage(verde, xInicial, yInicial, null);
		img.createGraphics().drawImage(vermelho, xInicial + 500, yInicial, null);
		
		img.createGraphics().drawImage(vermelho, xInicial, yInicial + 423, null);
		img.createGraphics().drawImage(verde, xInicial + 500, yInicial + 423, null);
		
		boolean draw_foto_1 = img.createGraphics().drawImage(foto1, x1, y1, null);
		boolean draw_foto_2 =img.createGraphics().drawImage(foto2, x2, y2, null);
		boolean draw_foto_3 =img.createGraphics().drawImage(foto3, x3, y3, null);
		boolean draw_foto_4 =img.createGraphics().drawImage(foto4, x4, y4, null);
		
		if(draw_foto_1) {
			System.out.println("Erro ao imprimir foto 1");
		}
		if(draw_foto_2) {
			System.out.println("Erro ao imprimir foto 2");
		}
		if(draw_foto_3) {
			System.out.println("Erro ao imprimir foto 3");
		}
		if(draw_foto_4) {
			System.out.println("Erro ao imprimir foto 4");
		}
		
		String diretorio = chaves.getDiretorioSecaoAnterior();
		File final_image = new File(diretorio,"cartao_" + secao + ".jpg");
		boolean final_Image_drawing = ImageIO.write(img, "jpeg", final_image);
		if(!final_Image_drawing) {
			System.out.println("Erro ao criar o cartão");
		}
		
		BufferedImage imgSalva = ImageIO.read(final_image);
		Image newImage = img.getScaledInstance(img.getWidth()*3, img.getHeight()*3, Image.SCALE_AREA_AVERAGING);
		ImageIO.write(imgSalva, "jpeg", final_image);
		
		return null;
	}

	@Override
	public int getUltimaSecao() {
		chaves = serializador.deserializeChaves();
		return chaves.getNumeroSecao() - 1;
	}

		
	@Override
	public void imprimir() throws PrintException, IOException {
		File foto = new File(chaves.getDiretorioImpressao(),chaves.getNomeCartaoAnterior());
		PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
		pras.add(new Copies(1));
		pras.add(MediaSizeName.ISO_A6);
		//pras.add(new MediaPrintableArea(0, 0, 4, 6,MediaPrintableArea.INCH));
		pras.add(OrientationRequested.LANDSCAPE);
		//pras.add(PrintQuality.DRAFT);
		//pras.add(new PrinterResolution(96, 96, ResolutionSyntax.DPI));
		
		PrintService pss[] = PrintServiceLookup.lookupPrintServices(DocFlavor.INPUT_STREAM.JPEG, null);
		if (pss.length == 0)
		  throw new RuntimeException("No printer services available.");
		
		PrintService ps = null;
		for(PrintService print : pss) {
			if(print.getName().contains(ParamUtil.getImpressora())) {
				ps = print;
			}
		}
		if(ps == null) {
			Logger.getLogger(Janela.class.toString()).log(Level.SEVERE, "Impressora não conectada");
			return;
		}
		Logger.getLogger(Janela.class.toString()).log(Level.SEVERE, "Imprimindo em " + ps);
		DocPrintJob job = ps.createPrintJob();
		FileInputStream fin = new FileInputStream(foto);
		DocFlavor flavor = DocFlavor.INPUT_STREAM.JPEG; 
		Doc doc = new SimpleDoc(fin, flavor, null); 
		job.print(doc, pras);
		fin.close();
	}

	@Override
	public Image getUltimaFotoSecao() {
		int secao = getUltimaSecao();
		File finalImage = new File(chaves.getDiretorioImpressao(), "secao_" + secao + ".jpg");
		try {
			return ImageIO.read(finalImage);
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}
	


}
